跳到主要内容

结构模式-过滤器模式

过滤器模式是什么?

过滤器模式(Filter Pattern)或称为标准模式(Criteria Pattern)这种模式允许开发人员使用不同的标准来过滤 一组对象(数组、List),通过逻辑运算以解耦的方式把它们连接起来。当我们想要选择满足一个或多个条件的对象子集时就可以使用这个模式(例如 FilterOutputStream 就是用的这个模式)

可以简化成如下这样,只传入一个 List,过滤出来也是一个 List

classDiagram Client --> Filter Filter <|-- ConcreteFilter1 Filter <|-- ConcreteFilter2 Filter: <<interface>> Filter: +List filter() ConcreteFilter1: +List filter() ConcreteFilter2: +List filter()

过滤器使用实例

举个例子,定义一个 Person 类,人是有很多不同的爱好的,例如打球、玩游戏、画画、写作,那如何一组 Person 类进行筛选呢?或者筛选出有两种爱好的人?

创建应用类


public class Person {

private String name;
private String gender;
private String maritalStatus;

public Person(String name, String gender, String maritalStatus){
this.name = name;
this.gender = gender;
this.maritalStatus = maritalStatus;
}

public String getName() {
return name;
}
public String getGender() {
return gender;
}
public String getMaritalStatus() {
return maritalStatus;
}
}

创建条件接口

public interface Criteria {
public List<Person> meetCriteria(List<Person> persons);
}

创建条件接口的实现类

创建实现 Criteria 接口的具体类。CriteriaMale.java , CriteriaFemale.java , CriteriaSingle.java , AndCriteria.java, OrCriteria.java

public class CriteriaMale implements Criteria {

@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> malePersons = new ArrayList<Person>();

for (Person person : persons) {
if(person.getGender().equalsIgnoreCase("MALE")){
malePersons.add(person);
}
}
return malePersons;
}
}
public class CriteriaFemale implements Criteria {

@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> femalePersons = new ArrayList<Person>();

for (Person person : persons) {
if(person.getGender().equalsIgnoreCase("FEMALE")){
femalePersons.add(person);
}
}
return femalePersons;
}
}
public class CriteriaSingle implements Criteria {

@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> singlePersons = new ArrayList<Person>();

for (Person person : persons) {
if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
singlePersons.add(person);
}
}
return singlePersons;
}
}
public class AndCriteria implements Criteria {

private Criteria criteria;
private Criteria otherCriteria;

public AndCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}

@Override
public List<Person> meetCriteria(List<Person> persons) {

List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
return otherCriteria.meetCriteria(firstCriteriaPersons);
}
}
public class OrCriteria implements Criteria {

private Criteria criteria;
private Criteria otherCriteria;

public OrCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}

@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

for (Person person : otherCriteriaItems) {
if(!firstCriteriaItems.contains(person)){
firstCriteriaItems.add(person);
}
}
return firstCriteriaItems;
}
}

测试:使用不同的条件及其组合来过滤人员

public class CriteriaPatternDemo {
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();

persons.add(new Person("Robert","Male", "Single"));
persons.add(new Person("John", "Male", "Married"));
persons.add(new Person("Laura", "Female", "Married"));
persons.add(new Person("Diana", "Female", "Single"));
persons.add(new Person("Mike", "Male", "Single"));
persons.add(new Person("Bobby", "Male", "Single"));

Criteria male = new CriteriaMale();
Criteria female = new CriteriaFemale();
Criteria single = new CriteriaSingle();
Criteria singleMale = new AndCriteria(single, male);
Criteria singleOrFemale = new OrCriteria(single, female);

System.out.println("Males: ");
printPersons(male.meetCriteria(persons));

System.out.println("\nFemales: ");
printPersons(female.meetCriteria(persons));

System.out.println("\nSingle Males: ");
printPersons(singleMale.meetCriteria(persons));

System.out.println("\nSingle Or Females: ");
printPersons(singleOrFemale.meetCriteria(persons));
}

public static void printPersons(List<Person> persons){

for (Person person : persons) {
System.out.println("Person : [ Name : " + person.getName() + ", Gender : " + person.getGender() + ", Marital Status : " + person.getMaritalStatus() + " ]");
}
}
}

验证输出:


Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : John, Gender : Male, Marital Status : Married ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]

Females:
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]

Single Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]

Single Or Females:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]